// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "GameFramework/Actor.h"
#include <Sockets.h>
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Engine.h"
#include "ODWorkerThread.h"
#include "Runtime/Networking/Public/Networking.h"
#include "Socket_Tibony.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FMyRecv, FString, IP, const TArray<uint8>&, data); 

UCLASS(BlueprintType, Blueprintable)
class SOCKET_PLUGIN_API USocket_Tibony : public UObject
{
	GENERATED_BODY()
public:
	USocket_Tibony();
	~USocket_Tibony();

	UFUNCTION(BlueprintCallable, Category = "UDP")
		void StartUDPReceiver(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort, bool& success, FName Platform);
	UFUNCTION(BlueprintCallable, Category = "UDP")
		void CloseUDPReceiver();
	UFUNCTION(BlueprintCallable, Category = "UDP")
		void DataRecv();
	UFUNCTION(BlueprintCallable, Category = "UDP")
		void UDPSendTo(FString IP, int32 Port, const TArray<uint8>& DataBuffer);
	UFUNCTION(BlueprintCallable, Category = "UDP")
		void UDPCreateSender(int32 SendBufferSize = 1048576);
	UFUNCTION(BlueprintCallable, Category = "UDP")
		void CloseUDPSender(FName Platform);
	UFUNCTION(BlueprintCallable, Category = "UDP")
		FString	 GetLocalIP();
	UFUNCTION(BlueprintCallable, Category = "UDP")
		bool ReceivedData();

	//UPROPERTY(BlueprintAssignable)
		FMyRecv  ReceiveDataEvent;

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
		bool  EnableThread;

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
		bool  EnableSocket;

	int32 packetSize = 1024;
	TArray<uint8> innerBuffer;
	int32 currentSize;

	UFUNCTION(BlueprintCallable, Category = "UDP")
		bool SetLength(int32 NewSize /*= 0*/);

	ISocketSubsystem* SocketSubsystem;

	FCriticalSection ct;

	class FMyODWorkerThread* CurrentInnerThread = nullptr;
	class FRunnableThread* CurrentThread = nullptr;


	bool FormatIP4ToNumber(const FString& IpAddress, uint8(&Out)[4]);
	FSocket* UDPSendSocket;

	FSocket* ListenSocket;

	
};
